"""
= django-taxonomy =

Django taxonomy is a taxonomy application for django. It supports translation of terms
along with their description.

== Features ==

 * translation of terms
 * render term (with or without related object previews)
 * breadcrumb based on term hierarchy
 * render taxonomy term lists (with or without related object count)
 * render taxonomy tag cloud
 * render taxonomy tag tower
 * term specific RSS feeds
 * sitemap framework integration
 * django admin taxonomy pane to easily organize term relations with drag & drop
 * link term to a view (rendering the view instead of the term)

== Description ==

At it's core, the taxonomy application just provide a Term model which can be used
in your own model via a foreign key or a many to many field.

But, there's more then that to it! django-taxonomy provides a lot of tool to help you
render those relations in your site. Those tool try to be as configurable as possible
so one can really control the display of taxonomy related information.

The django-taxonomy modules can also be used as a user configurable menu system for
your sites. To that end, an object (the view bridge) was added to the application. When
configured and assigned to a term of the taxonomy, the term will return the target view
response instead of rendering itself when hit.

It is also possible to have a term render as if it was one of your model instance.

The url of each term is constructed by converting it's name to a slug and hierarchy is
taken into acount when building an url. So if term a has a name of 'A Term' and term b,
his parent, has a name of 'Parent Term', then the url of term a relative to the taxonomy
root would be: parent-term/a-term

Finally, sitemap & rss feeds functionality are provided for integration with your sites
rss feeds and sitemap.

== Integration & Usage ==

=== Installation ===

In order to use the taxonomy app, you need to install it in your python path. To test if the
installation work, use your django project shell:
{{{
$python ./manage.py shell
>>> import taxonomy
>>>
}}}
Also, you will need to copy or link the taxonomy/media directory some place where you can serve
those static files.

=== Taxonomy Settings  & URLS ===

==== settings.py ====

in your settings.py project file, you will need to add the following lines:
{{{
TAXONOMY_MEDIA_PREFIX = '/path/to/taxonomy/media/files/'
}}}
where the '/path/to/taxonomy/media/files/' is the path that will be added by the taxonomy
application to the url to retrieve the taxonomy static files.
{{{
TAXONOMY_JQUERY_URL = '/path/to/jquery.js'
}}}
You can ommit this settings if you don't have (or don't want to use) jquery. If you do set the
jquery path, jquery will only be included in the admin taxonomy pane in the django admin interface.

If set, the taxonomy hierarchy editor will be enabled in the django admin under '/admin/taxonomy'

If you already include jquery in your django admin, you can then only set TAXONOMY_JQUERY_URL to True

The taxonomy application expects jquery 1.3.2
{{{
TAXONOMY_MODELS = (
    ('path.to.app1', 'Model1,Model2'),
    ('path.to.app2', 'Model3'),
)
}}}
Here, you specify which model will have a field that express a relation to a taxonomy term.
For exemple, if you have a django app named 'blog' in your project and you want to add taxonomy support
for your models 'Post' and 'Comment' in that application you'd have:
{{{
TAXONOMY_MODELS = (
    ('blog', 'Post,Comment'),
)
}}}
==== urls.py ====

in your URLconfs, you will need to include the following:
{{{
urlpatterns = patterns('',
    #...
    # To enable the hierarchy editor in the admin interface, should come before
    # the include of django admin.
    (r'^admin/taxonomy/', include('taxonomy.adminurls')),
    #...
    # To enable taxonomy urls (only 1 actually)
    (r'^taxonomy/', include('taxonomy.urls')),
    #...
}}}
If you want, you can add the view directly in your own URLconfs instead of including taxonomy.urls.
This way, you'll be able to provide your own template name to render terms.
{{{
(r'^(?P<path>[\w\d\/-]+)$', 'taxonomy.views.render', {'template_name':'your_template.html'}),
}}}
==== models.py ====

in order for one of your model to support taxonomy, you'll need to import the term model &
to add a foreign key or many  to many fields to the model. Also, you'll need to add the Taxonomy
subclass to your model, to specify taxonomy options.
{{{
from django.db import models
from taxonomy.models import Term

class MyModel(models.Model):
    term = models.ForeignKey(Term)

    class Taxonomy:
        fields = ['term',] # mandatory
        title = 'mymodel_title' # mandatory
        description = 'mymodel_description' # mandatory
        pubdate = 'mymodel_published_date' # use when using either the sitemap or feed functionality
        author = 'mymodel_author' # use when using feed functionality
        changefreq = 'mymodel_changefreq' # use with sitemap
        priority = 'mymodel_priority' # use with sitemap
        url = 'mymodel_url' # use only if the taxonomy app provided url don't suits you
        template_name = 'mymodeltemplate.html' # specify with which template file the taxonomy app
                                               # should render this model.
}}}
All of the attribute title, description, pubdate, author, changefreq, priority and url can take
either a field name or a member function name that will be called to sets the value.

fields is specified as a list as you might have multiple different relations with taxonomy terms.

Finaly, the template_name is the complete path where django can finds the template file use to render
this model. The following dictionnary is passed to the template when rendering it:
{{{
{
    'term': The term that was used to reach your model
    'model_instance': the model instance
    'breadcrumb': The current breadcrumb (including your model instance)
}
}}}
==== sitemap & feeds ====

If you use either the sitemap or syndication framework, django-taxonomy provides you with to class
to help integrating your taxonomy content to them.

The TaxonomySitemap class will provide an URL for each model that specify the required Taxonomy
configuration fields + the term in which your flagged the 'include_in_sitemap' field.
{{{
sitemaps = {
    ...
    'taxonomy':TaxonomySitemap,
}
}}}
If you would like to provide a feed based on a specific taxonomy term, you can use the class
TermFeed which will provide an entry for each model that specify the required taxonomy configuration
fields.
{{{
feeds = {
    'myfeed':TermFeed('term_name')
}
}}}
The title of the feed will be set to the term name but you can override that by passing a title to the TermFeed __init__:
{{{
feeds = {
    'myfeed':TermFeed('term_name', 'feed title')
}
}}}
=== Term Settings ===

When you create a term, aside from the normal stuff like, name, description, language and the like,
you have several options to adjust their rendering behavior:

 * use_bridge: specify the view bridge object to use, if any. Setting this field will call the related view instead of rendering the field when a render request is made for that term.
 * display_children_counts: when true, list generated from this term will display the object count along with the term name.
 * render_as_instance: when true, if only one object is associated with this term, render the object instead of the term.
 * render_teasers: when true, render teaser of associated objects when rendering the term.
 * include_in_sitemap: treat this term as a page when building the sitemap.

=== Term Translation ===

To translate a term in a given language, you need to create a TermTranslation object which specify the name and description for this language. This is accessible through the Term admin changelist as a term inline.

=== Template Tags ===

To use taxonomy template tags in your template, you'll need to load the taxonomy tags:
{{{
{% load taxonomy %}
}}}
The following tags are available:
{{{
{% taxonomy_render_term term page num_items %}: render the given term.
}}}
 * term: the term to render
 * page: optional, specify the current page for the term renderer paginator.
 * num_items: number of object related to term to display on a single page.
{{{
{% taxonomy_render_list term active_term depth %}: render a taxonomy terms list.
}}}
 * term: the term to grab the list from (term children will be the list item)
 * active_term: use to set the 'taxonomy-active' css class to the that term.
 * depth: specify the maximum depth of the list.
{{{
{% taxonomy_render_cloud term min_size max_size %}: render a taxonomy cloud (a tag cloud)
}}}
 * term: use all children of this term in the cloud
 * min_size: the minimum font size to use express in %
 * max_size: the maximum font size to use express in %
{{{
{% taxonomy_render_tower term min_size max_size %}: render a taxonomy tower (a tag list ordered by count)
}}}
 * term: use all children of this term in the cloud
 * min_size: the minimum font size to use express in %
 * max_size: the maximum font size to use express in %

=== CSS Classes ===

 * taxonomy-active: use to indicate that an item in a taxonomy list is the current one.
 * taxonomy-term: identify divs that wraps a term
 * taxonomy-term-children: identify a div that wraps a term children
 * taxonomy-term-instances: identify a div that wraps a term related instances
 * taxonomy-term-instance: idendify a div that wraps a term related instance
 * taxonomy-term-read-more: wraps the read more link of an instance teaser
 * taxonomy-pagination: when pagination is necessary for a term, wraps the pagination links.

=== The View Bridge ===

The last piece of django-taxonomy is the view bridge object.

The view bridge can be used to link a term to one of your view.

 * name: user friendly name to use when selecting a bridge for a term.
 * path: path to your view as if you were importing it ('blog.views.render_post')
 * params: a regular expression in the same format as URLconfs to grab view arguments.
 * default_params: a default path to pass as argument to the view is none is passed.

=== Glossary ===

Just a word about nomenclature. In the code, the word 'instance' or 'model_instance' is used
to represents an object that is related to a Term via a foreign key or many to many field.

=== Disclaimer ===

The django-taxonomy application is still in its infancy. pre-alpha... A lot of bugs still haunts its lines of
codes. Be kind an report those bug at:

http://code.google.com/p/django-taxonomy/issues/entry

This way, we can bring this application to stability!
"""
